package org.JQbitorrentClinet.utils;

import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.HttpEntity;
import org.apache.http.NameValuePair;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.*;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

@Slf4j
//TODO 设为包私有，不在项目外访问
public class InternalHttpClient {
    CloseableHttpClient httpClient = HttpClients.createDefault();
    String Cookie;

    @SneakyThrows
    public CloseableHttpResponse get(String url){
        url = fixUrl(url);
        log.trace("Get:{}", url);
        HttpGet request = new HttpGet(url);
        setCookie(request);

        return httpClient.execute(request);
    }

    @SneakyThrows
    public CloseableHttpResponse get(String url,Map params){
        url = fixUrl(url);
        log.trace("GetwithParams:{}", url);
        URIBuilder uriBuilder = new URIBuilder(url);

        for (Object key : params.keySet()) {
            uriBuilder.setParameter(key.toString(), params.get(key).toString());
        }
        HttpGet request = new HttpGet(uriBuilder.build());
        setCookie(request);

        return httpClient.execute(request);
    }

    @SneakyThrows
    public CloseableHttpResponse post(String url) {
        url = fixUrl(url);
        log.trace("post:{}", url);
        URIBuilder uriBuilder = new URIBuilder(url);

        HttpPost request = new HttpPost(uriBuilder.build());
        setCookie(request);

        return httpClient.execute(request);
    }


    @SneakyThrows
    public CloseableHttpResponse postMultiPart(String url, Map<String, Object> multipart) {
        url = fixUrl(url);
        log.trace("PostMultiPart:{}", url);

        MultipartEntityBuilder multipartEntityBuilder = MultipartEntityBuilder.create();
        for (Map.Entry<String, Object> entry : multipart.entrySet()) {
            multipartEntityBuilder.addTextBody(entry.getKey(), entry.getValue().toString());
        }
        HttpEntity entity  = multipartEntityBuilder.build();

        HttpPost httpPost = new HttpPost(url);
        setCookie(httpPost);
        httpPost.setEntity(entity);


        return httpClient.execute(httpPost);
    }

    @SneakyThrows
    public CloseableHttpResponse postBodyParm(String url, Map<String, Object> form) {
        url = fixUrl(url);
        log.trace("PostFormBodyPart:{}", url);

        List<NameValuePair> params = new ArrayList<>();
        for (Map.Entry<String, Object> entry : form.entrySet()) {
            BasicNameValuePair pair = new BasicNameValuePair(entry.getKey(), entry.getValue().toString());
            params.add(pair);
        }
        HttpPost httpPost = new HttpPost(url);
        setCookie(httpPost);
        httpPost.setEntity(new UrlEncodedFormEntity(params));

        return httpClient.execute(httpPost);
    }

    @SneakyThrows
    public CloseableHttpResponse deleteBodyParam(String url, Map<String, Object> params) {
        url = fixUrl(url);
        log.trace("DeleteFormBodyPart:{}", url);

        URIBuilder uriBuilder = new URIBuilder(url);

        for (Map.Entry<String, Object> entry : params.entrySet()) {
            uriBuilder.setParameter(entry.getKey(), entry.getValue().toString());
        }

        HttpDelete httpDelete = new HttpDelete(uriBuilder.build());
        setCookie(httpDelete);

        return httpClient.execute(httpDelete);
    }

    private String fixUrl(String url) {
        if (!url.startsWith("http://") && !url.startsWith("https://")) {
            url = "http://" + url;
        }
        return url;
    }

    private HttpRequestBase setCookie(HttpRequestBase request) {
        request.setHeader("Cookie", getCookie());
        return request;
    }

    public String getCookie() {
        if(Cookie == null)
            return "";

        return Cookie;
    }

    public void setCookie(String cookie) {
        Cookie = cookie;
    }
}
